# ui/components/config_dialog.py
"""
配置对话框组件 - 完整修复版本
负责配置项的创建和编辑
"""

import tkinter as tk
from tkinter import ttk, messagebox
from typing import Dict, Any, List, Optional, Tuple


class ConfigDialog:
    """配置对话框 - 完整修复版本"""

    def __init__(self, parent, column_names: List[str], existing_configs: List[Dict] = None,
                 edit_config: Dict = None):
        self.parent = parent
        self.column_names = column_names
        self.existing_configs = existing_configs or []
        self.edit_config = edit_config
        self.result = None

        # 创建对话框
        self.dialog = tk.Toplevel(parent)
        self.dialog.title("编辑配置项" if edit_config else "添加配置项")
        self.dialog.geometry("500x600")
        self.dialog.resizable(False, False)
        self.dialog.transient(parent)
        self.dialog.grab_set()

        # 设置对话框位置（居中）
        self.dialog.update_idletasks()
        x = parent.winfo_x() + (parent.winfo_width() - self.dialog.winfo_width()) // 2
        y = parent.winfo_y() + (parent.winfo_height() - self.dialog.winfo_height()) // 2
        self.dialog.geometry(f"+{x}+{y}")

        # 创建界面
        self.create_widgets()

        # 绑定事件
        self.bind_events()

        # 如果是编辑模式，加载配置数据
        if edit_config:
            self.load_config_data()

    def create_widgets(self):
        """创建界面组件"""
        # 主框架
        main_frame = ttk.Frame(self.dialog, padding="15")
        main_frame.pack(fill=tk.BOTH, expand=True)

        # 基本配置区域
        basic_frame = ttk.LabelFrame(main_frame, text="基本配置", padding="10")
        basic_frame.pack(fill=tk.X, pady=(0, 10))

        # 启用状态
        self.enabled_var = tk.BooleanVar(value=True)
        ttk.Checkbutton(
            basic_frame,
            text="启用此配置项",
            variable=self.enabled_var
        ).pack(anchor=tk.W, pady=(0, 10))

        # 列选择
        column_frame = ttk.Frame(basic_frame)
        column_frame.pack(fill=tk.X, pady=5)

        ttk.Label(column_frame, text="Excel列名:").pack(side=tk.LEFT)
        self.column_var = tk.StringVar()
        self.column_combo = ttk.Combobox(
            column_frame,
            textvariable=self.column_var,
            values=self.column_names,
            state="readonly",
            width=30
        )
        self.column_combo.pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)

        # 输入方式
        input_frame = ttk.Frame(basic_frame)
        input_frame.pack(fill=tk.X, pady=5)

        ttk.Label(input_frame, text="输入方式:").pack(side=tk.LEFT)
        self.input_method_var = tk.StringVar(value="paste")

        input_methods = [
            ("粘贴方式", "paste"),
            ("键盘输入", "keyboard"),
            ("图片输入", "image")
        ]

        for text, value in input_methods:
            ttk.Radiobutton(
                input_frame,
                text=text,
                variable=self.input_method_var,
                value=value
            ).pack(side=tk.LEFT, padx=5)

        # 数据类型
        type_frame = ttk.Frame(basic_frame)
        type_frame.pack(fill=tk.X, pady=5)

        ttk.Label(type_frame, text="数据类型:").pack(side=tk.LEFT)
        self.data_type_var = tk.StringVar(value="auto")

        data_types = [
            ("自动检测", "auto"),
            ("文本", "str"),
            ("整数", "int"),
            ("小数", "float"),
            ("布尔值", "bool")
        ]

        type_combo = ttk.Combobox(
            type_frame,
            textvariable=self.data_type_var,
            values=[dt[0] for dt in data_types],
            state="readonly",
            width=15
        )
        type_combo.pack(side=tk.LEFT, padx=5)

        # 默认值
        default_frame = ttk.Frame(basic_frame)
        default_frame.pack(fill=tk.X, pady=5)

        ttk.Label(default_frame, text="默认值:").pack(side=tk.LEFT)
        self.default_value_var = tk.StringVar()
        default_entry = ttk.Entry(default_frame, textvariable=self.default_value_var, width=30)
        default_entry.pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)

        # 输入选项区域
        options_frame = ttk.LabelFrame(main_frame, text="输入选项", padding="10")
        options_frame.pack(fill=tk.X, pady=(0, 10))

        # 清除选项
        self.clear_before_input = tk.BooleanVar(value=True)
        ttk.Checkbutton(
            options_frame,
            text="输入前清除内容",
            variable=self.clear_before_input
        ).pack(anchor=tk.W, pady=2)

        # 回车确认
        self.enter_after_input = tk.BooleanVar(value=False)
        ttk.Checkbutton(
            options_frame,
            text="输入后按回车确认",
            variable=self.enter_after_input
        ).pack(anchor=tk.W, pady=2)

        # 延迟设置
        delay_frame = ttk.Frame(options_frame)
        delay_frame.pack(fill=tk.X, pady=5)

        ttk.Label(delay_frame, text="操作后延迟(秒):").pack(side=tk.LEFT)
        self.delay_after_var = tk.StringVar(value="0.5")
        delay_entry = ttk.Entry(delay_frame, textvariable=self.delay_after_var, width=8)
        delay_entry.pack(side=tk.LEFT, padx=5)

        # 数据转换区域
        transform_frame = ttk.LabelFrame(main_frame, text="数据转换", padding="10")
        transform_frame.pack(fill=tk.X, pady=(0, 10))

        # 字符串处理
        string_frame = ttk.Frame(transform_frame)
        string_frame.pack(fill=tk.X, pady=2)

        self.remove_whitespace = tk.BooleanVar(value=True)
        ttk.Checkbutton(
            string_frame,
            text="移除多余空格",
            variable=self.remove_whitespace
        ).pack(anchor=tk.W)

        # 替换规则
        replace_frame = ttk.Frame(transform_frame)
        replace_frame.pack(fill=tk.X, pady=2)

        ttk.Label(replace_frame, text="替换规则:").pack(side=tk.LEFT)
        self.replace_old_var = tk.StringVar()
        replace_old_entry = ttk.Entry(replace_frame, textvariable=self.replace_old_var, width=10)
        replace_old_entry.pack(side=tk.LEFT, padx=2)

        ttk.Label(replace_frame, text="→").pack(side=tk.LEFT, padx=2)

        self.replace_new_var = tk.StringVar()
        replace_new_entry = ttk.Entry(replace_frame, textvariable=self.replace_new_var, width=10)
        replace_new_entry.pack(side=tk.LEFT, padx=2)

        # 高级设置区域
        advanced_frame = ttk.LabelFrame(main_frame, text="高级设置", padding="10")
        advanced_frame.pack(fill=tk.X, pady=(0, 10))

        # 对应记录点
        point_frame = ttk.Frame(advanced_frame)
        point_frame.pack(fill=tk.X, pady=5)

        ttk.Label(point_frame, text="对应记录点:").pack(side=tk.LEFT)
        self.point_index_var = tk.StringVar(value="自动")
        point_combo = ttk.Combobox(
            point_frame,
            textvariable=self.point_index_var,
            values=["自动", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
            state="readonly",
            width=10
        )
        point_combo.pack(side=tk.LEFT, padx=5)

        # 描述信息
        desc_frame = ttk.Frame(advanced_frame)
        desc_frame.pack(fill=tk.X, pady=5)

        ttk.Label(desc_frame, text="描述:").pack(anchor=tk.W)
        self.desc_text = tk.Text(desc_frame, height=3, width=50)
        desc_scrollbar = ttk.Scrollbar(desc_frame, orient=tk.VERTICAL, command=self.desc_text.yview)
        self.desc_text.configure(yscrollcommand=desc_scrollbar.set)

        self.desc_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        desc_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        # 按钮区域
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(fill=tk.X, pady=(10, 0))

        ttk.Button(
            button_frame,
            text="确定",
            command=self.on_ok,
            style="Accent.TButton"
        ).pack(side=tk.RIGHT, padx=5)

        ttk.Button(
            button_frame,
            text="取消",
            command=self.dialog.destroy
        ).pack(side=tk.RIGHT)

        # 验证按钮
        ttk.Button(
            button_frame,
            text="验证配置",
            command=self.validate_config
        ).pack(side=tk.LEFT)

    def bind_events(self):
        """绑定事件"""
        self.dialog.bind('<Return>', lambda e: self.on_ok())
        self.dialog.bind('<Escape>', lambda e: self.dialog.destroy())

    def load_config_data(self):
        """加载配置数据（编辑模式）"""
        if not self.edit_config:
            return

        try:
            # 基本配置
            self.enabled_var.set(self.edit_config.get('enabled', True))
            self.column_var.set(self.edit_config.get('column_name', ''))
            self.input_method_var.set(self.edit_config.get('input_method', 'paste'))
            self.data_type_var.set(self.edit_config.get('data_type', 'auto'))
            self.default_value_var.set(str(self.edit_config.get('default_value', '')))

            # 输入选项
            self.clear_before_input.set(self.edit_config.get('clear_before_input', True))
            self.enter_after_input.set(self.edit_config.get('enter_after_input', False))
            self.delay_after_var.set(str(self.edit_config.get('delay_after', 0.5)))

            # 数据转换
            self.remove_whitespace.set(self.edit_config.get('remove_whitespace', True))

            transformations = self.edit_config.get('transformations', [])
            for transform in transformations:
                if transform.get('type') == 'replace':
                    self.replace_old_var.set(transform.get('old_value', ''))
                    self.replace_new_var.set(transform.get('new_value', ''))

            # 高级设置
            self.point_index_var.set(str(self.edit_config.get('point_index', '自动')))

            description = self.edit_config.get('description', '')
            self.desc_text.delete(1.0, tk.END)
            self.desc_text.insert(1.0, description)

        except Exception as e:
            messagebox.showerror("错误", f"加载配置数据失败: {e}", parent=self.dialog)

    def validate_config(self):
        """验证配置"""
        errors = []

        # 验证列名
        if not self.column_var.get():
            errors.append("请选择Excel列名")

        # 验证延迟时间
        try:
            delay = float(self.delay_after_var.get())
            if delay < 0 or delay > 60:
                errors.append("延迟时间必须在0-60秒之间")
        except ValueError:
            errors.append("延迟时间必须是数字")

        # 检查列名重复
        column_name = self.column_var.get()
        if column_name:
            for config in self.existing_configs:
                if config.get('column_name') == column_name and config != self.edit_config:
                    errors.append(f"列名 '{column_name}' 已被其他配置项使用")
                    break

        if errors:
            messagebox.showerror("配置验证失败", "\n".join(errors), parent=self.dialog)
            return False
        else:
            messagebox.showinfo("验证通过", "配置项验证通过", parent=self.dialog)
            return True

    def on_ok(self):
        """确定按钮处理"""
        if not self.validate_config():
            return

        try:
            # 构建配置结果
            self.result = {
                'enabled': self.enabled_var.get(),
                'column_name': self.column_var.get(),
                'input_method': self.input_method_var.get(),
                'data_type': self.data_type_var.get(),
                'default_value': self.default_value_var.get(),
                'clear_before_input': self.clear_before_input.get(),
                'enter_after_input': self.enter_after_input.get(),
                'delay_after': float(self.delay_after_var.get()),
                'remove_whitespace': self.remove_whitespace.get(),
                'point_index': self.point_index_var.get(),
                'description': self.desc_text.get(1.0, tk.END).strip()
            }

            # 添加转换规则（如果有）
            transformations = []
            if self.replace_old_var.get() and self.replace_new_var.get():
                transformations.append({
                    'type': 'replace',
                    'old_value': self.replace_old_var.get(),
                    'new_value': self.replace_new_var.get()
                })

            if transformations:
                self.result['transformations'] = transformations

            # 关闭对话框
            self.dialog.destroy()

        except Exception as e:
            messagebox.showerror("错误", f"保存配置失败: {e}", parent=self.dialog)

    def show(self):
        """显示对话框"""
        self.dialog.wait_window()
        return self.result